﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Smartee.RichText.VisitorAndBuilder;
using Smartee.RichText;

namespace Mls.Interpreters
{
    public class RichTextInterpreter : IMlsInterpreter
    {
        private class FontEntry
        {
            public FontConfiguration Font;
            public int IdInRichTextDoc;

            public FontEntry(string fontFamily, string fontName)
            {
                Font = new FontConfiguration(fontFamily, fontName);
                IdInRichTextDoc = -1;
            }
        }

        private Dictionary<Language.Type, List<FontEntry>> _fonts = new Dictionary<Language.Type, List<FontEntry>>();
        private Dictionary<Language.Type, int> _currentFontId = new Dictionary<Language.Type, int>();

        private IBuilder _builder;

        public RichTextInterpreter(IBuilder builder)
        {
            _builder = builder;
        }

        #region IMlsInterpreter Members

        public void StartHeader()
        {
            _builder.StartHeader();
        }

        public void EndHeader()
        {
            _builder.EndHeader();
        }

        public void StartFooter()
        {
            _builder.StartFooter();
        }

        public void EndFooter()
        {
            _builder.EndFooter();
        }

        public void StartDocument()
        {
            _builder.StartDocument();
            _builder.StartFontTable();
            FillFontTableForLanguage(Language.Type.Latin);
            FillFontTableForLanguage(Language.Type.Coptic);
            FillFontTableForLanguage(Language.Type.Greek);
            FillFontTableForLanguage(Language.Type.Arabic);
            _builder.EndFontTable();
        }

        public void EndDocument()
        {
            _builder.EndDocument();
        }

        public void StartParagraph(Justification justification, Language.Type language)
        {
            _builder.StartParagraph(justification, language == Language.Type.Arabic ? TextDirection.RightToLeft : TextDirection.LeftToRight);
            ChangeLanguage(language);
        }

        public void EndParagraph()
        {
            _builder.EndParagraph();
        }

        public void StartFootnote()
        {
            _builder.StartFootnote();
        }

        public void EndFootnote()
        {
            _builder.EndFootnote();
        }

        public void StartTable(ColumnDefinition[] columns)
        {
            TextDirection tableDirection = TextDirection.LeftToRight;

            if ((columns.Length > 0 && columns[0].Start > columns[0].End) ||
                (columns.Length > 1 && columns[0].Start > columns[1].Start))
                tableDirection = TextDirection.RightToLeft;

            _builder.StartTable(tableDirection,
                (from a in columns select new Measurement() { Inches = a.WidthInInches } ).ToArray(),
                (from a in columns select a.Justify) .ToArray());
        }

        public void StartRow()
        {
            _builder.StartRow();
        }

        public void StartCell()
        {
            _builder.StartCell();
        }

        public void EndCell()
        {
            _builder.EndCell();
        }

        public void EndRow()
        {
            _builder.EndRow();
        }

        public void EndTable()
        {
            _builder.EndTable();
        }

        public bool BoldFace
        {
            set { _builder.BoldFace = value; }
        }

        public bool Underline
        {
            set { _builder.Underline = value; }
        }

        public bool Strike
        {
            set { _builder.Strike = value; }
        }

        public void ChangeLanguage(Language.Type language)
        {
            _builder.CharacterDirection = language == Language.Type.Arabic ? TextDirection.RightToLeft : TextDirection.LeftToRight;
            _builder.FontId = _fonts[language][_currentFontId[language]].IdInRichTextDoc;
        }

        public void SetFont(Language.Type language, int fontId)
        {
            _currentFontId[language] = fontId;
        }

        public void InsertPageBreak()
        {
            _builder.InsertPageBreak();
        }

        public void InsertPageNumber()
        {
            _builder.InsertPageNumber();
        }

        public void InsertText(string text)
        {
            _builder.InsertText(text);
        }

        public void SkippedCommand(string content)
        {
            //throw new NotImplementedException();
        }

        #endregion

        public int AddFont(Language.Type language, string fontFamily, string fontName)
        {
            if (!_fonts.ContainsKey(language))
                _fonts[language] = new List<FontEntry>();

            _fonts[language].Add(new FontEntry(fontFamily, fontName));

            return _fonts[language].Count - 1;
        }

        private void FillFontTableForLanguage(Language.Type language)
        {
            _currentFontId[language] = 0;

            for (int i = 0; i < _fonts[language].Count; i++)
                _fonts[language][i].IdInRichTextDoc = _builder.AddFont(_fonts[language][i].Font.FontFamily, _fonts[language][i].Font.FontName);
        }
    }
}
